package web_mapper

import (
	"context"
	"gorm.io/gorm"
	"gorm.io/gorm/clause"
	"sync"
	"transport/web/web_model"
)

type OrderDetailMapper struct {
	DB   *gorm.DB
	Ctx  context.Context
	Lock *sync.RWMutex
}

func (mapper *OrderDetailMapper) Create(m *web_model.TransOrderDetail) (ret *web_model.TransOrderDetail, err error) {
	mapper.Lock.Lock()
	defer mapper.Lock.Unlock()
	if err := mapper.DB.WithContext(mapper.Ctx).Create(m).Error; err != nil {
		return nil, err
	}
	return m, nil
}
func (mapper *OrderDetailMapper) Upsert(m *web_model.TransOrderDetail) (ret *web_model.TransOrderDetail, err error) {
	if err = mapper.DB.WithContext(mapper.Ctx).Clauses(clause.OnConflict{
		Columns: []clause.Column{{Name: "order_code"}, {Name: "order_line_num"}},
		DoUpdates: clause.AssignmentColumns([]string{"product_name", "product_code", "product_en",
			"formula", "storage_type", "lot_num", "product_date", "expire_date", "count", "unit", "specifications", "manufacturer", "approval_num", "permit_holder", "approval_valid_time"}),
	}).Create(m).Error; err != nil {
		return nil, err
	}
	return m, nil
}
func (mapper *OrderDetailMapper) Update(m *web_model.TransOrderDetail) (ret *web_model.TransOrderDetail, err error) {
	mapper.Lock.Lock()
	defer mapper.Lock.Unlock()
	if err := mapper.DB.WithContext(mapper.Ctx).Model(&web_model.TransOrderDetail{}).Where("id = ?", m.ID).Updates(m).Error; err != nil {
		return nil, err
	}
	return m, nil
}
func (mapper *OrderDetailMapper) CreateOrUpdate(m *web_model.TransOrderDetail) (ret *web_model.TransOrderDetail, err error) {
	mapper.Lock.Lock()
	defer mapper.Lock.Unlock()
	if err := mapper.DB.WithContext(mapper.Ctx).Model(m).Save(m).Error; err != nil {
		return nil, err
	}
	return m, nil
}
func (mapper *OrderDetailMapper) QueryById(id int64) (m *web_model.TransOrderDetail, err error) {
	mapper.Lock.RLock()
	defer mapper.Lock.RUnlock()
	if err := mapper.DB.WithContext(mapper.Ctx).Model(&web_model.TransOrderDetail{}).Where("id = ?", id).First(&m).Error; err != nil {
		return nil, err
	}
	return m, nil
}
func (mapper *OrderDetailMapper) QueryOrderDetailsByBillId(billSn string) (m []*web_model.TransOrderDetail, err error) {
	mapper.Lock.RLock()
	defer mapper.Lock.RUnlock()
	if err := mapper.DB.WithContext(mapper.Ctx).Table("trans_order_detail").
		Where("EXISTS ( SELECT trans_order.id FROM trans_order WHERE trans_order.trans_bill_sn = ? AND trans_order.order_code = trans_order_detail.order_code )", billSn).Order("order_line_num").Find(&m).Error; err != nil {
		return nil, err
	}
	return m, nil
}
func (mapper *OrderDetailMapper) QueryByIds(ids []int64) (m []*web_model.TransOrderDetail, err error) {
	mapper.Lock.RLock()
	defer mapper.Lock.RUnlock()
	if err := mapper.DB.WithContext(mapper.Ctx).Model(&web_model.TransOrderDetail{}).Where("id IN ?", ids).Find(&m).Error; err != nil {
		return nil, err
	}
	return m, nil
}
func (mapper *OrderDetailMapper) DeleteById(id int64) (err error) {
	mapper.Lock.Lock()
	defer mapper.Lock.Unlock()
	if err := mapper.DB.WithContext(mapper.Ctx).Unscoped().Where("id = ?", id).Delete(&web_model.TransOrderDetail{}).Error; err != nil {
		return err
	}
	return nil
}

func (mapper *OrderDetailMapper) DeleteByIds(ids []int64) (err error) {
	mapper.Lock.Lock()
	defer mapper.Lock.Unlock()
	if err := mapper.DB.WithContext(mapper.Ctx).Unscoped().Where("id IN ?", ids).Delete(&web_model.TransOrderDetail{}).Error; err != nil {
		return err
	}
	return nil
}

func (mapper *OrderDetailMapper) Page(pageIndex, pageSize int, orderCode string) (items []*web_model.TransOrderDetail, count int64, err error) {
	mapper.Lock.RLock()
	defer mapper.Lock.RUnlock()
	var countTmp int64 = 0
	table := mapper.DB.WithContext(mapper.Ctx)
	if orderCode != "" {
		table = table.Where("order_code = ?", orderCode)
	}
	if err := table.Offset((pageIndex - 1) * pageSize).Limit(pageSize).Find(&items).Offset(-1).Limit(-1).Count(&countTmp).Error; err != nil {
		return nil, 0, err
	}
	return items, countTmp, nil
}
func (mapper *OrderDetailMapper) PageApp(pageIndex, pageSize int, orderCode string) (items []*web_model.TransOrderDetail, count int64, err error) {
	mapper.Lock.RLock()
	defer mapper.Lock.RUnlock()
	var countTmp int64 = 0
	table := mapper.DB.WithContext(mapper.Ctx)
	if orderCode != "" {
		table = table.Where("order_code = ?", orderCode)
	}
	if err := table.Offset((pageIndex - 1) * pageSize).Limit(pageSize).Find(&items).Offset(-1).Limit(-1).Count(&countTmp).Error; err != nil {
		return nil, 0, err
	}
	return items, countTmp, nil
}
func (mapper *OrderDetailMapper) List(orderCode string) (items []*web_model.TransOrderDetail, count int64, err error) {
	mapper.Lock.RLock()
	defer mapper.Lock.RUnlock()
	var countTmp int64 = 0
	table := mapper.DB.WithContext(mapper.Ctx)
	if orderCode != "" {
		table = table.Where("order_code =?", orderCode)
	}
	if err := table.Order("order_line_num").Find(&items).Offset(-1).Limit(-1).Count(&countTmp).Error; err != nil {
		return nil, 0, err
	}
	return items, countTmp, nil
}
